package com.fw.application.controller.open;


import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.fw.application.controller.FwGuessController;
import com.fw.constant.Constant;
import com.fw.system.web.dao.FwGuessMapper;
import com.fw.system.web.model.entity.FwGuess;
import com.fw.system.web.model.entity.FwLogs;
import com.fw.system.web.model.entity.FwMoneys;
import com.fw.system.web.model.entity.FwShangjiaDeal;
import com.fw.system.web.service.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;

@Slf4j
@Configuration      //1.主要用于标记配置类，兼备Component的效果。
@EnableScheduling   // 2.开启定时任务
@RequiredArgsConstructor
public class SaticScheduleTask {

    private final IFwShangjiaService shangjiaService;
    private final IFwUserService userService;
    private final IFwGuessService guessService;
    private final IFwUgJoinService ugJoinService;
    private final IFwRuleDatasService ruleDatasService;
    private final FwGuessMapper guessMapper;
    private final FwGuessController guessController;
    private final  IFwMoneysService moneysService;

    //3.添加定时任务

    /**
     * 查询商甲产出
     * (每小时执行一次)
     */
    @Scheduled(cron = "0 0 * * * ?")
    private void configureTasks() {
        shangjiaService.output();
        log.info("执行查询商甲产出定时任务时间: " + LocalDateTime.now());
    }

    /**
     * 查询商甲存储
     * (每小时执行一次)
     */
    //@Scheduled(cron = "0 0 * * * ?")
    @Deprecated
    private void storageTasks() {
        shangjiaService.shangJiaStorage();
        log.info("执行查询商甲存储定时任务时间: " + LocalDateTime.now());
    }

    /**
     * 查询120天未登录的用户,将其删除
     * (每天执行一次)
     */
    @Scheduled(cron = "0 0 0 1/1 * ?  ")
    private void removeUser() {
        //userService.delUser();
        log.info("执行查询120天未登录的用户,将其删除定时任务时间: " + LocalDateTime.now());
    }

    /**
     * 用户积分兑换
     * (每天执行一次)
     */
    @Scheduled(cron = "0 0 0 1/1 * ?  ")
    public void releaseDisappearTasks() {
        log.info("执行用户积分兑换定时任务开始时间: " + LocalDateTime.now());
        shangjiaService.usersReleaseDisappear();
        log.info("执行用户积分兑换定时任务结束时间: " + LocalDateTime.now());
    }

    @Scheduled(cron = "0 0 0 1/1 * ?  ")
    public void returnShangJiaById() {
        log.info("执行用户商甲退回定时任务开始时间: " + LocalDateTime.now());
        shangjiaService.returnShangJiaById();
        log.info("执行用户商甲退回定时任务开始时间: " + LocalDateTime.now());
    }

    /**
     * 用户锁仓商甲兑换
     * (每天执行一次)
     */
    @Scheduled(cron = "0 0 0 1/1 * ?  ")
    private void lockJiaTasks() {
        shangjiaService.releaseJia();
        shangjiaService.releaseFlag();
        log.info("执行用户锁仓商甲兑换定时任务时间: " + LocalDateTime.now());
    }

    /**
     * @Effect 竞猜房间时间到了，执行塞机器人，强制PK操作
     * @Author 姚
     * @Date 2021/7/2
     **/
    @Scheduled(cron = "0 0/20 * * * ?")
    private void guessRoomTimeOut() {
        Integer roomTime = ruleDatasService.getInteger(Constant.IsRuleData.GUESS_ROOM_MINUTE);
        LocalDateTime outTime = LocalDateTime.now().minusMinutes(roomTime);
        FwGuess guess = new FwGuess();
        guess.setCreateTime(outTime);
        //获取创建时间小于，超时时间的数据
        List<FwGuess> notFullRoom = guessMapper.getNotFullRoom(guess);
        if (notFullRoom == null) {
            return;
        }
        for (FwGuess fg : notFullRoom) {
            guessController.joinAuto(fg.getGuessId());
            guessController.guessPk(fg.getGuessId());
        }

        log.info("定时 竞猜房间 执行，执行" + notFullRoom.size() + "条");
    }

    /**
     * @Effect PK时间到了，PK
     * @Author 姚
     * @Date 2021/7/2
     **/
    @Scheduled(cron = "0/10 * * * * ?")
    private void PKTimeOut() {
        Integer pkTime = ruleDatasService.getInteger(Constant.IsRuleData.GUESS_PK_SECOND);
        LocalDateTime outTime = LocalDateTime.now().minusSeconds(pkTime);
        List<Object> guessIdList = guessService.listObjs(Wrappers.<FwGuess>lambdaQuery()
                .select(FwGuess::getGuessId)
                .isNull(FwGuess::getVictoryUserId)
                .isNotNull(FwGuess::getPkTime)
                .le(FwGuess::getPkTime, outTime));
        if (guessIdList == null) {
            return;
        }
        for (Object guessId : guessIdList) {
            guessController.guessPk(guessId.toString());
        }

        log.info("定时PK执行，执行" + guessIdList.size() + "条");
    }

    /**
     * 匹配时间到了
     *
     * @Effect 匹配时间到了，塞机器人
     * @Author 姚
     * @Date 2021/7/2
     **/
    @Scheduled(cron = "0/20 * * * * ?")
    private void matchTimeOut() {
        Integer PKTime = ruleDatasService.getInteger(Constant.IsRuleData.MATCH_AUTO_SECOND);
        LocalDateTime outTime = LocalDateTime.now().minusSeconds(PKTime);
        List<FwGuess> list = guessService.list(Wrappers.<FwGuess>lambdaQuery()
                .eq(FwGuess::getIsMatch, 1)
                .le(FwGuess::getUpdateTime, outTime));

        if (list == null) {
            return;
        }

        for (FwGuess fg : list) {
            guessController.joinAuto(fg.getGuessId());
        }

        log.info("定时 匹配 执行，执行" + list.size() + "条");
    }

    private final IFwShangjiaDealService shangjiaDealService;

    //释放超过31分钟未释放的锁定商甲交易数据
    @Scheduled(cron = "0 */5 * * * ?")
    public void shangjiaRelase() {
        shangjiaDealService.list(Wrappers.<FwShangjiaDeal>lambdaQuery().eq(FwShangjiaDeal::getIsLock, 1)).parallelStream().forEach(item -> {
            if (item.getLockTime().plusMinutes(32).compareTo(LocalDateTime.now()) <= 0) {
                shangjiaDealService.updateById(item.setIsLock(0));
            }
        });

    }

    //每天凌晨三点执行以下 检查重复释放删除日志还原钱包
    private final  IFwLogsService logsService;
    @Scheduled(cron = "0 0 2 * * ?")
    public void checkJiFen(){
        userService.list().parallelStream().forEach(item->{
            List<FwLogs> list = logsService.list(Wrappers.<FwLogs>lambdaQuery().eq(FwLogs::getBuiId, item.getId()).eq(FwLogs::getModelName, "积分模块").eq(FwLogs::getIsType, "兑换")
                    .last("and to_days(create_time) = to_days(now())"));
            if (list.size()>1){
                list.remove(0);
                FwMoneys moneys = moneysService.getOne(Wrappers.<FwMoneys>lambdaQuery().eq(FwMoneys::getUserId, item.getId()));
                list.forEach(items->{
                    moneys.setDisappear(moneys.getDisappear().add(new BigDecimal(items.getFormInfo())));
                    moneys.setIntegral(moneys.getIntegral().subtract(new BigDecimal(items.getFormInfo())));
                    moneysService.updateById(moneys);
                    logsService.getBaseMapper().deleteById(items);
                    FwLogs one = logsService.getOne(Wrappers.<FwLogs>lambdaQuery().eq(FwLogs::getBuiId, item.getId()).eq(FwLogs::getModelName, "消证模块").eq(FwLogs::getFormInfo, items.getFormInfo()).eq(FwLogs::getIsType, "支出")
                            .last("and to_days(create_time) = to_days(now())"));
                    if (one!=null){
                        logsService.getBaseMapper().deleteById(one);
                    }

                });
            }

        });

    }
}
